package com.hup.minicontroller.client.activity;

import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View.OnClickListener;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.util.Consumer;

import com.hup.minicontroller.client.ClientApplication;
import com.hup.minicontroller.client.model.AppConfig;
import com.hup.minicontroller.client.model.AppState;
import com.hup.minicontroller.client.model.LanBroadcastServer;
import com.hup.minicontroller.client.model.ScannedServerItem;
import com.hup.minicontroller.client.mvp.IClientHandler;
import com.hup.minicontroller.client.mvp.IClientHandler.ClientHandlerList;
import com.hup.minicontroller.client.mvp.IMainView;
import com.hup.minicontroller.client.service.BluetoothDeviceService;
import com.hup.minicontroller.client.service.LanBroadcastReceiverService;
import com.hup.minicontroller.client.service.MainService;
import com.hup.minicontroller.client.view.MainForm;
import com.hup.minicontroller.client.view.ScannedServerItemAdapter;
import com.hup.minicontroller.client.view.ScannedServerItemAdapter.ConnectButtonListener;
import com.hup.minicontroller.client.view.WaitingDialog;
import com.hup.minicontroller.common.constant.ControlActionConstant.FunctionButton;
import com.hup.minicontroller.common.constant.NetConstant.ConnectType;
import com.hup.minicontroller.common.framework.SubThreadHandler;
import com.hup.minicontroller.common.model.dto.ControlConfigDto;
import com.hup.minicontroller.common.model.dto.FullScreenTouchRequest;
import com.hup.minicontroller.common.netty.model.LoginResponsePacket;
import com.hup.minicontroller.common.util.ActivityUtil;
import com.hup.minicontroller.common.util.NetUtil;

import java.util.Collection;
import java.util.Objects;


public class MainActivity extends AppCompatActivity implements IMainView {
    private static final String TAG = MainActivity.class.getSimpleName();

    private MainForm form;
    private ScannedServerItemAdapter scannedServerItemAdapter;

    private AppState appState;
    private SubThreadHandler subThreadHandler;
    private ClientHandlerList clientHandlers;
    private IClientHandler lanClient, bluetoothClient;
    /**
     * true-当前是竖屏
     */
    private boolean isPortrait;
    private boolean isForeground;
    private NetSpeedRunner netSpeedRunner;
    private AlertDialog waitingDialog;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        appState = ClientApplication.getBean(MainService.class).getAppState();
        subThreadHandler = ClientApplication.getBean(SubThreadHandler.class);
        clientHandlers = ClientApplication.getBean(ClientHandlerList.class);
        bluetoothClient = clientHandlers.get(ConnectType.BLUETOOTH);
        lanClient = clientHandlers.get(ConnectType.LAN);
        netSpeedRunner = new NetSpeedRunner();

        Point size = new Point();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            //版本号是乱写的,5.1的系统报错:没有ContextWrapper.getDisplay方法,但是注释中没写这个方法从哪个版本开始用
            getWindowManager().getDefaultDisplay().getRealSize(size);
        } else {
            Objects.requireNonNull(getDisplay()).getRealSize(size);
        }
        isPortrait = size.x < size.y;//todo 处理转屏
        Log.i(TAG, "onCreate: isPortrait=" + isPortrait);

        initView();
        initListener();
        ClientApplication.putBean(IMainView.class, this);
        Log.i(TAG, "=====  已打开" + getClass().getSimpleName());
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        Log.i(TAG, "onRestoreInstanceState: ");
        //super.onRestoreInstanceState(savedInstanceState);//坑到家!转屏后onCreate后会传递错误的值给SeekBar
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
        isForeground = true;
        boolean connected = appState.getConnectedType() != null;
        form.updateViewByModel(connected);
        ActivityUtil.switchFullScreen(this, !connected);
        if (connected) {
            form.btnDisconnect.post(netSpeedRunner);
        } else {
            ClientApplication.executeIfExist(LanBroadcastReceiverService.class, s -> s.switchService(true));
            ClientApplication.executeIfExist(BluetoothDeviceService.class, s -> s.switchService(true));
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
        isForeground = false;
        ClientApplication.executeIfExist(LanBroadcastReceiverService.class, s -> s.switchService(false));
        ClientApplication.executeIfExist(BluetoothDeviceService.class, s -> s.switchService(false));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
    }

    @Override
    public void onBackPressed() {
        Log.i(TAG, "onBackPressed: ");
        finish();
        ClientApplication.removeBean(IMainView.class);
        ClientApplication.getBean(MainService.class).doTerminate();
    }

    private void initView() {
        Log.i(TAG, "initView: ");
        //全屏模式在styles.xml中配置
        setContentView(MainForm.RESOURCE_ID);
        form = new MainForm(this);
        AppConfig appConfig = appState.getAppConfig();
        form.txtToConnect.setText(appConfig.getLanInputIp());
        //服务端item
        form.txtHotspotGateway.setText(NetUtil.getGatewayIp(this, ""));
        scannedServerItemAdapter = new ScannedServerItemAdapter();
        form.lvScannedServer.setAdapter(scannedServerItemAdapter);

        if (appConfig.buttonFloaterX != AppConfig.NULL_BUTTON_FLOATER_LOCATION && appConfig.buttonFloaterY != AppConfig.NULL_BUTTON_FLOATER_LOCATION) {
            //此处坑到家,看方法注释
            form.buttonFloater.setLocationPercent(appConfig.buttonFloaterX, appConfig.buttonFloaterY);
        }
    }

    private void initListener() {
        //连接功能
        form.btnConnectLan.setOnClickListener(v -> doConnectLan());
        form.btnDisconnect.setOnClickListener(v -> {
            form.btnDisconnect.setEnabled(false);
            if (appState.getConnectedType() == ConnectType.LAN) {
                subThreadHandler.post(() -> lanClient.switchClient(false));
            } else {
                subThreadHandler.post(() -> bluetoothClient.switchClient(false));
            }
        });
        //热点和扫描到的服务端item的监听
        form.layoutHotspot.setOnClickListener(v -> form.txtHotspotGateway.setText(NetUtil.getGatewayIp(this, "")));
        form.btnConnectHotspot.setOnClickListener(v -> {
            form.txtToConnect.setText(form.txtHotspotGateway.getText().toString());
            doConnectLan();
        });
        scannedServerItemAdapter.setConnectButtonListener(new ConnectButtonListener() {
            @Override
            public void onConnect(ScannedServerItem item) {
                if (item.isLan()) {
                    String address = item.getLanBroadcastServer().getAddress();
                    form.txtToConnect.setText(address);
                    doConnectLan();
                } else {
                    appState.getAppConfig().setBluetoothServer(item.getBluetoothDevice());
                    waitingDialog = WaitingDialog.show(MainActivity.this, "连接中");
                    subThreadHandler.post(() -> bluetoothClient.switchClient(true));
                }
            }
        });
        //控制功能
        form.cbEnableScreen.setOnCheckedChangeListener((v, isChecked) -> {
            if (!v.isPressed()) return;
            Log.i(TAG, "cbEnableScreen: " + isChecked);
            //马上更新config,并通知server
            appState.getControlConfig().setEnableScreen(isChecked);
            onControlConfigChanged();
            subThreadHandler.post(() -> clientHandlers.forEach((Consumer<IClientHandler>)
                    IClientHandler::onControlConfigChanged));
        });
        form.sbFps.setValueChangedListener((value, fromUser) -> {
            if (!fromUser) return;
            Log.i(TAG, "sbFps: " + value);
            appState.getControlConfig().setFps(value);
            subThreadHandler.post(() -> clientHandlers.forEach((Consumer<IClientHandler>)
                    IClientHandler::onControlConfigChanged));
        });
        form.sbScreenSize.setValueChangedListener((value, fromUser) -> {
            if (!fromUser) return;
            Log.i(TAG, "sbScreenSize: " + value);
            appState.getControlConfig().setScreenSize(value);
            subThreadHandler.post(() -> clientHandlers.forEach((Consumer<IClientHandler>)
                    IClientHandler::onControlConfigChanged));
        });
        form.sbScreenQuality.setValueChangedListener((value, fromUser) -> {
            if (!fromUser) return;
            Log.i(TAG, "sbScreenQuality: " + value);
            appState.getControlConfig().setScreenQuality(value);
            subThreadHandler.post(() -> clientHandlers.forEach((Consumer<IClientHandler>)
                    IClientHandler::onControlConfigChanged));
        });
        //功能按钮
        OnClickListener functionButtonListener = v -> subThreadHandler.post(() -> clientHandlers.forEach((Consumer<IClientHandler>) i ->
                i.onFunctionButton((FunctionButton) v.getTag())));
        form.btnBack.setTag(FunctionButton.BACK);
        form.btnHome.setTag(FunctionButton.HOME);
        form.btnApp.setTag(FunctionButton.APP);
        form.buttonFloater.btnBack.setTag(FunctionButton.BACK);
        form.buttonFloater.btnHome.setTag(FunctionButton.HOME);
        form.buttonFloater.btnApp.setTag(FunctionButton.APP);
        form.btnBack.setOnClickListener(functionButtonListener);
        form.btnHome.setOnClickListener(functionButtonListener);
        form.btnApp.setOnClickListener(functionButtonListener);
        form.buttonFloater.btnBack.setOnClickListener(functionButtonListener);
        form.buttonFloater.btnHome.setOnClickListener(functionButtonListener);
        form.buttonFloater.btnApp.setOnClickListener(functionButtonListener);
        form.screenView.setTouchEventCallback((action, xPercent, yPercent) -> subThreadHandler.post(() -> {
            FullScreenTouchRequest request = new FullScreenTouchRequest(action, xPercent, yPercent);
            clientHandlers.forEach((Consumer<IClientHandler>) i -> i.onFullScreenTouch(request));
        }));
        form.touchPadView.setTouchEventCallback((touchPadTouch) -> subThreadHandler.post(() ->
                clientHandlers.forEach((Consumer<IClientHandler>) i -> i.onTouchPadTouch(touchPadTouch))
        ));
    }

    @Override
    public void onConnectResult(LoginResponsePacket loginResponse) {
        if (waitingDialog != null) {
            waitingDialog.dismiss();
            waitingDialog = null;
        }
        if (!isForeground) return;
        if (appState.getConnectedType() == null && !isPortrait) {
            //断开时不是竖屏,转成竖屏
            setPortrait(true);
            return;
        }
        form.btnDisconnect.post(netSpeedRunner);
        runOnUiThread(() -> {
            if (loginResponse != null && !loginResponse.isSuccess() && loginResponse.getErrorMessage() != null) {
                Toast.makeText(this, loginResponse.getErrorMessage(), Toast.LENGTH_SHORT).show();
            }
            boolean connected = appState.getConnectedType() != null;
            if (connected) scannedServerItemAdapter.clear();
            ActivityUtil.switchFullScreen(this, !connected);
            form.onConnectionChanged();
        });
    }

    @Override
    public void onConnectionLost() {
        onConnectResult(null);
    }

    @Override
    public void onChannelIdle() {
        if (!isForeground) return;
        runOnUiThread(() -> Toast.makeText(this, "服务端连接丢失", Toast.LENGTH_SHORT).show());
    }

    @Override
    public void onControlConfigChanged() {
        if (!isForeground) return;
        runOnUiThread(() -> {
            ControlConfigDto controlConfig = appState.getControlConfig();
            Log.i(TAG, "onControlConfigChanged: " + controlConfig);
            form.updateControlComponents(controlConfig);
            //触控板模式:固定成竖屏
            boolean isTouchPad = controlConfig.isEnableControl() && !controlConfig.isEnableScreen();
            if (isTouchPad && !isPortrait) setPortrait(true);
        });
    }

    @Override
    public void onScreenData(Bitmap screenData) {
        if (!isForeground) return;
        runOnUiThread(() -> {
            if (!appState.getControlConfig().isEnableScreen()) {
                return;//本机按了[不传输图像]后,需要打开[触摸板模式],切换竖屏,需要过滤服务端剩余图像
            }
            //根据图像切换屏幕方向
            int width = screenData.getWidth();
            int height = screenData.getHeight();
            boolean needPortrait = width < height;
            if (needPortrait && !isPortrait) {//竖屏
                setPortrait(true);
            } else if (!needPortrait && isPortrait) {//横屏
                setPortrait(false);
            }
            form.screenView.setScreenImage(screenData);
        });
    }

    /**
     * @param b true-设置成竖屏
     */
    private void setPortrait(boolean b) {
        Log.i(TAG, "setPortrait: " + b);
        isPortrait = b;
        setRequestedOrientation(b ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    private void doConnectLan() {
        waitingDialog = WaitingDialog.show(MainActivity.this, "连接中");
        appState.getAppConfig().setLanInputIp(form.txtToConnect.getText().toString());
        subThreadHandler.post(() -> lanClient.switchClient(true));
    }

    @Override
    public void onScannedBroadcastServer(Collection<LanBroadcastServer> broadcastServers) {
        if (!isForeground || appState.getConnectedType() != null) return;
        runOnUiThread(() -> scannedServerItemAdapter.setLanBroadcastServer(broadcastServers));
    }

    @Override
    public void onScannedBluetooth(Collection<BluetoothDevice> bluetoothDevices) {
        if (!isForeground || appState.getConnectedType() != null) return;
        runOnUiThread(() -> scannedServerItemAdapter.setBluetoothDevice(bluetoothDevices));
    }

    /**
     * 更新网速功能
     */
    private class NetSpeedRunner implements Runnable {

        @Override
        public void run() {
            if (!isForeground || appState.getConnectedType() == null) return;
            StringBuilder sb = new StringBuilder();
            clientHandlers.forEach((Consumer<IClientHandler>) i -> i.getSpeedText(sb));
            form.txtNetSpeed.setText(sb.toString());
            form.btnDisconnect.postDelayed(this, 1000);
        }
    }

}
